import React, {useState, useEffect, useRef} from 'react';
import './App.css';

const getItemMsg = (id, list) => {
    let msgItem = {};
    list.map(item => {
        if (item.id === id) {
            msgItem = item
        }
    });
    list = null;
    msgItem.pid = id;
    return msgItem
}

const dragStopActive = {
    onMouseDown: (e) => {
        // e.preventDefault();
        e.stopPropagation();
    },
    onDragStart: (e) => {
        // e.preventDefault();
        e.stopPropagation();
    },
    onDrag: (e) => {
        // e.preventDefault();
        e.stopPropagation();
    },
    onDragEnd: (e) => {
        // e.preventDefault();
        e.stopPropagation();
    }
}

const MoveItem = (props) => {
    const onDragStartActive = (ev) => {
        props.onDragStartActive(`item-${props.id}-${props.index}`, props.index, ev, props.id, props.pid)
    }

    const enterBodyActive = (ev) => {
        document.getElementById(`list-item-body-${props.id}`).style.border = "1px solid #00a0e9";
        props.onDragBody(props.id, props.index, ev)
    }

    const dragLeaveActive = (ev) => {
        document.getElementById(`list-item-body-${props.id}`).style.border = "0 none";
        // props.onDragLeave(props.id, props.pid, props.index);

    }

    return (
        <div
            key={`item-${props.id}`}
            id={`item-${props.id}-${props.index}`}
            style={{margin: '0px auto 20px auto'}}
            datapid={props.pid}
            className={"move-active-item"}
            draggable
            onDragStart={onDragStartActive}
            onDrag={props.dragActive}
            onDragEnd={props.dragEndActive}
            // onDragLeave={() => {props.onDragLeave(props.id, props.pid, props.index)}}
        >
            <h4  onClick={() => {console.log(111111)}} onDragEnter={() => {props.onDragEnter(props.id, props.pid, props.index)}} >{props.item.title} -- {props.pid} -- {props.index}</h4>
            <div className="desc-ele" {...dragStopActive}>{props.item.desc}</div>
            {
                props.item.type === 2 &&
                <div  
                    id={`list-item-body-${props.id}`} 
                    className="list-item-body" 
                    {...dragStopActive} 
                    onDragEnter={enterBodyActive} 
                    onDragLeave={dragLeaveActive}
                >
                    大body题部分大body题部分大body题部分大body题部分大body题部分大body题部分大body题部分
                    {
                        props.listMap[props.id]?.map((item, index) => (
                            <MoveItem key={item}
                                      item={getItemMsg(item, JSON.parse(JSON.stringify(props.list)))}
                                      id={item}
                                      pid={props.id}
                                      index={index}
                                      onDragStartActive={props.onDragStartActive}
                                      dragActive={props.dragActive}
                                      dragEndActive={props.dragEndActive}
                                      onDragEnter={props.onDragEnter}
                                      onDragBody={props.onDragBody}
                                      onDragLeave={props.onDragLeave}
                                      list={JSON.parse(JSON.stringify(props.list))}
                                      listMap={JSON.parse(JSON.stringify(props.listMap))}
                            />
                        ))
                    }
                </div>
            }
        </div>
    )
}

const Test1 = () => {
    const [list, setList] = useState([]);
    const dataRef = useRef(null);
    const moveRef = useRef(null);
    const activeRef = useRef(null);
    const moveDataRef = useRef(null);
    const changeItemDataRef = useRef(null);
    const leaveBody = useRef(null);

    const [listObj, setListObj] = useState({
        list: [],
        relations: {}
    });

    useEffect(() => {
        dataRef.current = "";
        fetch("./list.json").then(response => {
            response.json().then(msg => {
                setListObj(msg)
            }).catch(err => {
                console.error(err)
            })
        }).catch(err => {
            console.error(err)
        })
    }, [])

    const onDragStartActive = (id, index, ev, itemId, itemPid) => {
        moveRef.current = {
            ele: document.getElementById(id),
            item: itemId,
            pid: itemPid,
            indexNum: index
        };
        activeRef.current = index;
        moveDataRef.current = ev.clientY;
        dataRef.current = document.getElementById(id).getClientRects();
    };
    const dragActive = (ev) => {
        moveDataRef.current = ev.clientY;
        moveRef.current.ele.style.opacity = "0";
    };
    const dragEndActive = (ev) => {
        moveDataRef.current = ev.clientY;
        moveRef.current.ele.style.opacity = "1";
        exchangeListActive(changeItemDataRef.current, moveRef.current)
    };

    const onDragEnter = (changeItem, changePid, index) => {
        changeItemDataRef.current = {
            item: changeItem, 
            pid: changePid,
            indexNum: index
        }
        if (changePid !== moveRef.current.pid) {
            activeRef.current = index;
        } else {
            activeRef.current = moveRef.current.indexNum;
        }
        transformActive(changePid, index)
    }

    const onDragBody = (changePid, pidIndex, ev) => {
        if(changeItemDataRef.current?.pid !== changePid) {
            let enterDirection = "up";
            if (ev.clientY <= moveDataRef.current) {
                enterDirection = "down"
            }
            if (listObj.relations[changePid] && enterDirection === "down") {
                console.log(listObj.relations[changePid].length)
                onDragEnter(0, changePid, listObj.relations[changePid].length - 1)
            } else {
                onDragEnter(0, changePid, 0)
            }
        }
        
    }

    const onDragLeave = (changeItem, changePid, index) => {
        if (changeItem === leaveBody.current) return;
        leaveBody.current = changeItem;
        console.log(index);
        // onDragEnter(changeItem, changePid, index)
        changeItemDataRef.current = {
            item: changeItem, 
            pid: changePid,
            indexNum: index
        }
        if (changePid !== moveRef.current.pid) {
            activeRef.current = index;
        } else {
            activeRef.current = moveRef.current.indexNum;
        }
    }

    const transformActive = (pid, indexNum) => {
        let activeList = listObj.relations[pid] || [];

        console.log(indexNum + '-------' + activeRef.current)

        for (let i = Math.min(indexNum, activeRef.current); i <= Math.max(indexNum, activeRef.current); i++) {
            if (document.getElementById(`item-${activeList[i]}-${i}`)) {
                transformActiveItem(document.getElementById(`item-${activeList[i]}-${i}`), i, pid);
            }
        }
        //move-up-active
    }

    const transformActiveItem = (ele, indexNum, pid) => {
        if (parseInt(ele.getAttribute('datapid')) !== parseInt(pid)) return;
        if ([...ele.classList].includes("move-up-active") && indexNum === changeItemDataRef.current.indexNum) {
            ele.classList.remove("move-up-active");
            return;
        }
        if ([...ele.classList].includes("move-down-active") && indexNum === changeItemDataRef.current.indexNum) {
            ele.classList.remove("move-down-active");
            return;
        }
        if (activeRef.current < indexNum) {
            ele.classList.add("move-up-active")
            return;
        }
        ele.classList.add("move-down-active");
    }

    const exchangeListActive = (changeData, moveData) => {
        let relations = {...listObj.relations};
        let list = [...listObj.list];

        relations[moveData.pid].splice(moveData.indexNum, 1); //不管如何先把初始位置的干掉
        if (!relations[changeData.pid]) {
            console.log(1111)
            relations[changeData.pid] = [];
        }
        relations[changeData.pid].splice(changeData.indexNum, 0, moveData.item);
        dataRef.current = null;
        moveRef.current = null;
        activeRef.current = null;
        moveDataRef.current = null;
        changeItemDataRef.current = null;
        leaveBody.current = null;
        
        setListObj({
            list: list,
            relations: relations
        })       
    }

    useEffect(() => {
        let activeUpList = [...document.getElementsByClassName('move-up-active')];
        let activeDownList = [...document.getElementsByClassName('move-down-active')];
        activeUpList.map(item => {
            item.classList.remove("move-up-active")
        });
        activeDownList.map(item => {
            item.classList.remove("move-down-active")
        });
        activeUpList = undefined;
        activeDownList = undefined;

    }, [listObj])

    return (
        <div className="App">
             {
                listObj.relations["0"]?.map((item,index) => (
                      <MoveItem key={item}
                                pid={"0"}
                                index={index}
                                item={getItemMsg(item, [...listObj.list])}
                                id={item}
                                onDragStartActive={onDragStartActive}
                                dragActive={dragActive}
                                dragEndActive={dragEndActive}
                                onDragEnter={onDragEnter}
                                onDragBody={onDragBody}
                                onDragLeave={onDragLeave}
                                list={JSON.parse(JSON.stringify(listObj.list))}
                                listMap={JSON.parse(JSON.stringify(listObj.relations))}
                        />
                ))
            }
        </div>
    )
};

export default Test1;